import base64
import pickle
from django.shortcuts import render
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response

from goods.models import SKU
from . import serializers
from django_redis import get_redis_connection


class CartView(GenericAPIView):
    serializer_class = serializers.CartSerializer

    # 重写方法
    def perform_authentication(self, request):
        pass

    def post(self, request):
        # 1.获取数据
        dict_data = request.data

        # 2.获取序列化器
        serializer = self.get_serializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        # 3.获取数据
        sku_id = serializer.data.get("sku_id")
        count =serializer.data.get("count")
        selected =serializer.data.get("selected", True)
        try:
            user = request.user
        except Exception as e:
            user = None

        # 4.判断用户状态
        if user and request.user.is_authenticated:
            # 4.1获取redis对象
            redis_conn = get_redis_connection("cart")

            # 4.2增加购物车商品数量
            redis_conn.hincrby("cart_%s" % user.id, sku_id, count)

            # 4.3判断是否选中
            if selected:
                redis_conn.sadd("cart_selected_%s" % user.id, sku_id)

            # 4.4返回
            return Response(serializer.data)
        else:
            # 5.1获取cookie购物车数据
            cookie_cart = request.COOKIES.get("cart")

            # 5.2判断是否有购物车数据， 转换字典格式
            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            # 5.3累加
            if sku_id in cookie_dict:
                count += cookie_dict[sku_id].get("count", 0)

            # 5.4设置新的数据到字典
            cookie_dict[sku_id] = {
                "count": count,
                "selected": selected
            }

            # 5.5将字典转换字符串， 写入到cookie
            response = Response(status=200)
            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie("cart", cookie_cart)

            # 5.6返回响应
            return response

    def get(self, request):

        # 1.获取用户数据
        try:
            user = request.user
        except Exception as e:
            user = None

        # 2.判断用户登陆状态
        if user and request.user.is_authenticated:
            # 2.1.获取redis中用户购物车数据
            redis_conn = get_redis_connection("cart")
            redis_cart_dict = redis_conn.hgetall("cart_%s" % user.id)
            redis_cart_selected_list = redis_conn.smembers("cart_selected_%s"% user.id)

            # 2.2.数据拼接
            sku_list = []
            for sku_id, count in redis_cart_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "selected": sku_id in redis_cart_selected_list,
                    "default_image_url": sku.default_image_url,
                    "name": sku.name,
                    "price": sku.price,
                    "count": int(count),
                    "id": sku.id
                }
                sku_list.append(sku_dict)

            # 2.3.返回响应
            return Response(sku_list)

        else:
            # 3.获取cookie中的数据
            cookie_cart = request.COOKIES.get("cart")

            # 4.转换成字典
            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            # 5.拼接数据
            sku_list = []
            for sku_id, count_selected in cookie_dict.items():
                sku = SKU.objects.get(id=sku_id)
                sku_dict = {
                    "selected": count_selected["selected"],
                    "default_image_url": sku.default_image_url,
                    "name": sku.name,
                    "price": sku.price,
                    "count": int(count_selected["count"]),
                    "id": sku.id
                }
                sku_list.append(sku_dict)

            # 6.返回响应
            return Response(sku_list)

    def put(self, request):
        # 1.获取参数
        dict_data = request.data

        # 2.获取序列化器，校验
        serializer = self.get_serializer(data = dict_data)
        serializer.is_valid(raise_exception=True)

        # 3.获取数据
        sku_id = serializer.data.get("sku_id")
        count = serializer.data.get("count")
        selected = serializer.data.get("selected")
        try:
            user = request.user
        except Exception as e:
            user = None

        # 4.判断用户登陆状态
        if user and request.user.is_authenticated:
            # 4.1获取redis
            redis_conn = get_redis_connection("cart")

            # 4.2修改
            redis_conn.hset("cart_%s" % user.id, sku_id, count)

            if selected:
                redis_conn.sadd("cart_selected_%s" % user.id, sku_id)
            else:
                redis_conn.srem("cart_selected_%s" % user.id, sku_id)

            # 4.3返回
            return Response(serializer.data)

        else:
            # 5.1获取cookie数据
            cookie_cart = request.COOKIES.get("cart")

            # 5.2转换字典
            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            # 5.3修改
            cookie_dict[sku_id] = {
                "count": count,
                "selected": selected
            }

            # 5.4转换字符串返回
            response = Response(serializer.data)
            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie("cart", cookie_cart)
            return response

    def delete(self, request):

        # 1.获取参数
        dict_data = request.data

        # 2.创建序列化器，校验
        serializer = serializers.CartDeleteSerializer(data=dict_data)
        serializer.is_valid(raise_exception=True)

        # 3.获取数据
        sku_id = serializer.data.get("sku_id")
        count = serializer.data.get("count")
        selected = serializer.data.get("selected")

        try:
            user = request.user
        except Exception as e:
            user = None

        # 4.判断用户状态
        if user and request.user.is_authenticated:
            # 4.1删除redis中的数据
            redis_conn = get_redis_connection("cart")
            redis_conn.hdel("cart_%s" % user.id, sku_id)
            redis_conn.srem("cart_selected_%s" % user.id, sku_id)

            # 4.2返回响应
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            # 5.1获取cookie数据
            cookie_cart = request.COOKIES.get("cart")

            # 5.2转换字典
            cookie_dict = {}
            if cookie_cart:
                cookie_dict = pickle.loads(base64.b64decode(cookie_cart.encode()))

            # 5.3删除
            if sku_id in cookie_dict:
                del cookie_dict[sku_id]

            # 5.4返回响应
            response = Response(serializer.data)
            cookie_cart = base64.b64encode(pickle.dumps(cookie_dict)).decode()
            response.set_cookie("cart", cookie_cart)
            return response

